/**
 * Copyright (c) 2023 myons Inc. All rights reserved.
 */
package cn.zmwh.im.server.config.datasource;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.zaxxer.hikari.HikariDataSource;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import java.util.List;

/**
 * @describe: 、
 * @author: dmzmwh 、
 * @time: 2023-12-28 13:54 、
 */
@Setter
@Getter
@Configuration
public class DataSourceConfig {
    @Autowired
    DataSourceProperties dataSourceProperties;
    @Autowired
    DbSourceProperties dbSourceProperties;

    /**
     * 自定义的数据源DynamicRoutingDataSource添加到Spring容器里面去
     */
    @Bean
    @Primary
    public DynamicRoutingDataSource dataSource() {
        List<DBConfig> configs = dbSourceProperties.getConfigs();
        DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();
        DataSource masterDataSource = dataSourceProperties.initializeDataSourceBuilder().build();
        dynamicRoutingDataSource.addDataSource("master", masterDataSource);
        if (CollUtil.isNotEmpty(configs)) {
            for (DBConfig config : configs) {
                List<DbProperties> dbs = config.getDbs();
                String name = config.getName();
                int logIndex = 0;
                for (DbProperties item : dbs) {
                    String host = item.getHost();
                    String password = item.getPassword();
                    String username = item.getUsername();
                    String dbName = item.getDbName();
                    String logicDbName = name + "_" + logIndex;
                    if (StrUtil.isBlank(dbName)) {
                        dbName = logicDbName;
                    }
                    DataSourceBuilder<?> dataSourceBuilder = DataSourceBuilder.create();
                    dataSourceBuilder.driverClassName("com.mysql.cj.jdbc.Driver");
                    if (host.contains(":")) {
                        dataSourceBuilder.url("jdbc:mysql://" + host + "/" + dbName + "?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true");
                    } else {
                        dataSourceBuilder.url("jdbc:mysql://" + host + ":3306/" + dbName + "?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true");
                    }
                    dataSourceBuilder.username(username);
                    dataSourceBuilder.password(password);

                    HikariDataSource build = (HikariDataSource) dataSourceBuilder.build();

                    build.setMinimumIdle(10);
                    build.setMaximumPoolSize(600);
                    build.setConnectionTimeout(30000);
                    build.setIdleTimeout(180000);
                    build.setMaxLifetime(1800000);
//                If your driver supports JDBC4 we strongly recommend not setting this property.
//                This is for "legacy" drivers that do not support the JDBC4 Connection.isValid() API.
//                This is the query that will be executed just before a connection is given toyou from the pool to validate that the connection to the database is still alive.
//                Again, try running the pool without this property,
//                HikariCP will log an error if your driver is not JDBC4 compliant to let you know. Default: none
//                build.setConnectionTestQuery("SELECT 1");
                    dynamicRoutingDataSource.addDataSource(logicDbName, build);
                    logIndex++;
                }
            }
        }
        return dynamicRoutingDataSource;
    }
}
